#ifndef RINGBUFFER_H
#define RINGBUFFER_H

#ifdef __cplusplus
extern "C" {
#endif

#include "public.h"
#include <stddef.h>
#include <stdint.h>

/**
 * @brief 环形缓冲区结构体
 */
typedef struct ringbuffer
{
    uint8_t *buffer; // 指向环形缓冲区的指针
    size_t size;     // 缓冲区大小
    size_t head;     // 头指针，指向下一个写入位置
    size_t tail;     // 尾指针，指向下一个读取位置
} _ringbuffer_t, *ringbuffer_t;

/**
 * @brief 创建一个指定大小的环形缓冲区
 * @param size 缓冲区大小
 * @return 返回环形缓冲区指针，失败返回NULL
 */
ringbuffer_t ringbuffer_creat(size_t size);

/**
 * @brief 销毁环形缓冲区，释放内存
 * @param rb 环形缓冲区指针
 * @return 0成功，-1失败
 */
int ringbuffer_destroy(ringbuffer_t rb);

/**
 * @brief 初始化环形缓冲区，使用外部buffer
 * @param rb 环形缓冲区指针
 * @param buffer 外部缓冲区指针
 * @param size 缓冲区大小
 * @return 0成功，-1失败
 */
int ringbuffer_init(ringbuffer_t rb, uint8_t *buffer, size_t size);

/**
 * @brief 写入数据到环形缓冲区，若空间不足则覆盖旧数据
 * @param rb 环形缓冲区指针
 * @param data 待写入数据指针
 * @param len 写入数据长度
 * @return 实际写入的数据长度，失败返回-1
 */
int ringbuffer_write(ringbuffer_t rb, const uint8_t *data, size_t len);

/**
 * @brief 从环形缓冲区读取数据
 * @param rb 环形缓冲区指针
 * @param data 读取数据存放指针
 * @param len 读取数据长度
 * @return 实际读取的数据长度，失败返回-1
 */
int ringbuffer_read(ringbuffer_t rb, uint8_t *data, size_t len);

/**
 * @brief 判断环形缓冲区是否为空
 * @param rb 环形缓冲区指针
 * @return 1为空，0非空，-1参数错误
 */
static inline int ringbuffer_empty(ringbuffer_t rb)
{
    if (!rb) return -1;
    return rb->head == rb->tail;
}

/**
 * @brief 判断环形缓冲区是否已满
 * @param rb 环形缓冲区指针
 * @return 1为满，0未满，-1参数错误
 */
static inline int ringbuffer_full(ringbuffer_t rb)
{
    if (!rb) return -1;
    return ((rb->head + 1) % rb->size) == rb->tail;
}

/**
 * @brief 获取环形缓冲区中可用数据长度
 * @param rb 环形缓冲区指针
 * @return 可用数据长度，失败返回-1
 */
int ringbuffer_available(ringbuffer_t rb);

/**
 * @brief 获取环形缓冲区剩余可写空间
 * @param rb 环形缓冲区指针
 * @return 剩余空间长度，失败返回-1
 */
int ringbuffer_space(ringbuffer_t rb);

/**
 * @brief 预览读取数据但不移动指针
 * @param rb 环形缓冲区指针
 * @param data 读取数据存放指针
 * @param len 读取数据长度
 * @return 实际读取的数据长度，失败返回-1
 */
int ringbuffer_peek(ringbuffer_t rb, uint8_t *data, size_t len);

/**
 * @brief 清空环形缓冲区数据
 * @param rb 环形缓冲区指针
 * @return 0成功，-1失败
 */
int ringbuffer_flush(ringbuffer_t rb);

/**
 * @brief 重置环形缓冲区指针（等价于flush）
 * @param rb 环形缓冲区指针
 * @return 0成功，-1失败
 */
static inline int ringbuffer_reset(ringbuffer_t rb)
{
    return ringbuffer_flush(rb);
}

/**
 * @brief 写入单字节到环形缓冲区，若空间不足则覆盖旧数据
 * @param rb 环形缓冲区指针
 * @param data 待写入的单字节数据
 * @return 1为成功，0为失败
 */
int ringbuffer_write_byte(ringbuffer_t rb, uint8_t data);

/**
 * @brief 从环形缓冲区读取单字节数据
 * @param rb 环形缓冲区指针
 * @param data 读取到的单字节数据指针
 * @return 1为成功，0为失败
 */
int ringbuffer_read_byte(ringbuffer_t rb, uint8_t *data);

#ifdef __cplusplus
}
#endif

#endif // RINGBUFFER_H